package com.javacoo.junit.generator.internal.util;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.URL;
import java.net.URLClassLoader;
import java.net.URLDecoder;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

import com.github.javaparser.JavaParser;
import com.github.javaparser.ast.CompilationUnit;
import com.github.javaparser.ast.ImportDeclaration;
import com.github.javaparser.ast.NodeList;
import com.github.javaparser.ast.body.FieldDeclaration;
import com.github.javaparser.ast.body.MethodDeclaration;
import com.github.javaparser.ast.body.TypeDeclaration;
import com.github.javaparser.symbolsolver.JavaSymbolSolver;
import com.github.javaparser.symbolsolver.resolution.typesolvers.CombinedTypeSolver;
import com.github.javaparser.symbolsolver.resolution.typesolvers.JarTypeSolver;
import com.github.javaparser.symbolsolver.resolution.typesolvers.JavaParserTypeSolver;
import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver;
import com.javacoo.junit.generator.api.ProgressCallback;

/**
 * Javaparser 工具类
 * <li></li>
 *
 * @author: duanyong@jccfc.com
 * @since: 2021/1/21 9:43
 */
public class JavaparserUtility {
    /**
     * 文件合并
     * <li></li>
     * @author duanyong@jccfc.com
     * @date 2021/1/21 9:44
     * @param newCompilationUnit: 新文件
     * @param existingCompilationUnit: 旧文件
     * @return: java.lang.String 合并后的文件内容
     */
    public static String mergerFile(CompilationUnit newCompilationUnit,CompilationUnit existingCompilationUnit){
        //合并Imports
        //需要新增的Imports
        List<ImportDeclaration> newImports = newCompilationUnit.getImports().stream().filter(importDeclaration -> !existingCompilationUnit.getImports().stream().anyMatch(imp->imp.getName().equals(importDeclaration.getName()))).collect(Collectors.toList());
        if(newImports != null && !newImports.isEmpty()){
            existingCompilationUnit.getImports().addAll(newImports);
        }
        NodeList<TypeDeclaration<?>> oldTypes = existingCompilationUnit.getTypes();
        NodeList<TypeDeclaration<?>> types = newCompilationUnit.getTypes();

        for (int i = 0;i<oldTypes.size();i++) {
            //合并fields
            //取出新对象fields
            List<FieldDeclaration> fields = types.get(i).getFields();
            //取出旧对象fields
            List<FieldDeclaration> oldFields = oldTypes.get(i).getFields();
            //需要新增的fields
            List<FieldDeclaration> newFields = fields.stream().filter(fieldDeclaration -> !oldFields.contains(fieldDeclaration)).collect(Collectors.toList());
            if(newFields != null && !newFields.isEmpty()){
                oldFields.addAll(newFields);
            }

            //合并Methods
            //取出新对象Methods
            List<MethodDeclaration> methods = types.get(i).getMethods();
            //取出旧对象Methods
            List<MethodDeclaration> oldMethods = oldTypes.get(i).getMethods();
            //需要新增的Methods
            List<MethodDeclaration> newMethods = methods.stream().filter(methodDeclaration -> !oldMethods.stream().anyMatch(method->method.getName().equals(methodDeclaration.getName()))).collect(Collectors.toList());
            if(newMethods != null && !newMethods.isEmpty()){
                oldMethods.addAll(newMethods);
            }
        }
        return existingCompilationUnit.toString();
    }
    /**
     * 根据文件，获取CompilationUnit对象
     * <li></li>
     * @author duanyong@jccfc.com
     * @date 2021/1/21 15:20
     * @param file:文件
     * @return: java.util.Optional<com.github.javaparser.ast.CompilationUnit>
     */
    public static Optional<CompilationUnit> getCompilationUnit(File file) throws FileNotFoundException {
        return new JavaParser().parse(file).getResult();
    }
    /**
     * 初始化Javaparser
     * <li></li>
     * @author duanyong@jccfc.com
     * @date 2021/1/26 15:13
     * @param callback:进度回调接口
     * @return: JavaSymbolSolver
     */
    public static JavaSymbolSolver initJavaparser(ProgressCallback callback) throws IOException {
        URLClassLoader cl = (URLClassLoader) Thread.currentThread().getContextClassLoader();
        CombinedTypeSolver typeSolver = new CombinedTypeSolver(new ReflectionTypeSolver());
        URL[] urls = cl.getURLs();
        for(URL url : urls){
            callback.startTask("url.getProtocol()="+url.getProtocol()+","+url.toString());
            // 得到文件路径
            String urlFile = url.getFile();
            // 如果是jar包
            if (urlFile.contains(".jar")) {
                typeSolver.add(new JarTypeSolver(urlFile));
            }else{
                // 获取包的物理路径
                String filePath = URLDecoder.decode(urlFile, "UTF-8");
                typeSolver.add(new JavaParserTypeSolver(new File(filePath)));
            }
        }
        JavaSymbolSolver symbolSolver = new JavaSymbolSolver(typeSolver);
        return symbolSolver;
    }
}
